package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.GravityCompat;

import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.example.myapplication.databinding.ActivityWeatherBinding;
import com.example.myapplication.gson.AQI;
import com.example.myapplication.gson.BingPic;
import com.example.myapplication.gson.Forecast;
import com.example.myapplication.gson.HourlyWeather;
import com.example.myapplication.gson.NowWeather;
import com.example.myapplication.gson.Suggest;
import com.example.myapplication.gson.TotalWeather;
import com.example.myapplication.util.HttpUtil;
import com.example.myapplication.util.Utility;
import com.google.gson.Gson;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;


public class WeatherActivity extends AppCompatActivity {
    ActivityWeatherBinding binding;
    public static final String FORECAST_URL="https://p36tunnkj5.re.qweatherapi.com/v7/weather/7d";
    public static final String AQI_URL="https://p36tunnkj5.re.qweatherapi.com/v7/air/now";
    public static final String SUGGEST_URL="https://p36tunnkj5.re.qweatherapi.com/v7/indices/1d";
    public static final String NOWEATHER_URL="https://p36tunnkj5.re.qweatherapi.com/v7/weather/now";
    public static final String HOURLY_URL="https://p36tunnkj5.re.qweatherapi.com/v7/weather/24h";
    public static final String KEY="facdd2a695eb45e8b6d3a8849f790351";
    private String current_province;
    private String current_city;
    private String current_county;
    private String type="1,3,8";
    private String mWeatherId;  // 添加成员变量保存天气ID

    // 新增：安全字符串方法，避免null
    private String safeString(String s) {
        return s == null ? "" : s;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT >= 21) {
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }

        binding = ActivityWeatherBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // 设置导航按钮点击事件
        binding.includeTitle.navButton.setOnClickListener(v -> {
            binding.drawerLayout.openDrawer(GravityCompat.START);
        });

        // 设置下拉刷新的颜色
        binding.swipeRefresh.setColorSchemeResources(R.color.purple_500);

        // 添加监听器，只有在顶部才能刷新
        binding.weatherLayout.getViewTreeObserver().addOnScrollChangedListener(() -> {
            binding.swipeRefresh.setEnabled(binding.weatherLayout.getScrollY() == 0);
        });

        binding.includeTitle.titleCity.setOnClickListener(v -> {
            binding.drawerLayout.openDrawer(GravityCompat.START);
        });

        // 设置下拉刷新监听器
        binding.swipeRefresh.setOnRefreshListener(() -> {
            if (mWeatherId != null) {
                requestWeather(mWeatherId);
            }
        });

        loadBingPic();

        SharedPreferences sp = getSharedPreferences("weather",MODE_PRIVATE);
        String location = sp.getString("location","");
        String json = sp.getString("weather","");
        String updateTime = sp.getString("updateTime","");
        if(!TextUtils.isEmpty(json)){
            // 有缓存时直接解析天气数据
            Gson gson=new Gson();
            TotalWeather totalWeather = gson.fromJson(json, TotalWeather.class);
            mWeatherId = sp.getString("weatherId", "");  // 从缓存中读取天气ID
            showNowWeatherInfo(totalWeather.getNowWeather());
            showForecastInfo(totalWeather.getForecast());
            showAQIInfo(totalWeather.getAqi());
            showSuggestInfo(totalWeather.getSuggest());
            // 这里用safeString避免null
            binding.includeTitle.titleCity.setText(safeString(location));
            binding.includeTitle.titleUpdateTime.setText(updateTime);
        } else {
            // 无缓存时去服务器查询天气
            Intent intent = getIntent();
            String weatherId = intent.getStringExtra("weather_id");
            current_province = intent.getStringExtra("current_province");
            current_city = intent.getStringExtra("current_city");
            current_county = intent.getStringExtra("current_county");
            // 这里用safeString避免null
            binding.includeTitle.titleCity.setText(String.format("%s %s %s", safeString(current_province), safeString(current_city), safeString(current_county)));
            weatherId = weatherId.substring(2);
            mWeatherId = weatherId;  // 保存天气ID
            requestWeather(weatherId);
        }
    }

    private void loadBingPic() {
        String url = "https://api.xygeng.cn/openapi/bing/";
        HttpUtil.sendOkHttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Toast.makeText(WeatherActivity.this, "获取Bing每日图片失败", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String result = response.body().string();
                BingPic bingPic = new Gson().fromJson(result, BingPic.class);
                Log.d("TAG23", result);
                runOnUiThread(() -> {
                    if (bingPic != null && bingPic.getCode() == 200) {
                        // 显示图片
                        Glide.with(WeatherActivity.this).load(bingPic.getData().getUrl()).into(binding.bingPicImg);
                    } else {
                        Toast.makeText(WeatherActivity.this, "获取Bing每日图片失败", Toast.LENGTH_SHORT).show();
                    }
                });
            }

        });
    }

    private void requestWeather(String location) {
        loadBingPic();
        String url0 = NOWEATHER_URL + "?" + "location=" + location + "&key=" + KEY;
        String url1 = FORECAST_URL + "?" + "location=" + location + "&key=" + KEY;
        String url2 = AQI_URL + "?" + "location=" + location + "&key=" + KEY;
        String url3 = SUGGEST_URL + "?" + "location=" + location + "&key=" + KEY + "&type=" + type;
        String url4 = HOURLY_URL + "?" + "location=" + location + "&key=" + KEY;

        Gson gson = new Gson();

        Observable<Response> observable0 = HttpUtil.request(url0);
        Observable<Response> observable1 = HttpUtil.request(url1);
        Observable<Response> observable2 = HttpUtil.request(url2);
        Observable<Response> observable3 = HttpUtil.request(url3);
        Observable<Response> observable4 = HttpUtil.request(url4);

        Observable.zip(
                observable0,
                observable1,
                observable2,
                observable3,
                observable4,
                (response0, response1, response2, response3, response4) -> {
                    try {
                        NowWeather nowWeather = gson.fromJson(response0.body().string(), NowWeather.class);
                        Forecast forecast = gson.fromJson(response1.body().string(), Forecast.class);
                        AQI aqi = gson.fromJson(response2.body().string(), AQI.class);
                        Suggest suggest = gson.fromJson(response3.body().string(), Suggest.class);
                        HourlyWeather hourlyWeather = gson.fromJson(response4.body().string(), HourlyWeather.class);

                        TotalWeather totalWeather = new TotalWeather();
                        totalWeather.setNowWeather(nowWeather);
                        totalWeather.setAqi(aqi);
                        totalWeather.setForecast(forecast);
                        totalWeather.setSuggest(suggest);
                        totalWeather.setHourlyWeather(hourlyWeather);

                        String toWrite = gson.toJson(totalWeather);
                        SharedPreferences sp = getSharedPreferences("weather", MODE_PRIVATE);
                        SharedPreferences.Editor editor = sp.edit();
                        editor.putString("weather", toWrite);
                        editor.putString("weatherId", location);
                        editor.putString("location", String.format("%s %s %s", 
                            safeString(current_province), 
                            safeString(current_city), 
                            safeString(current_county)));

                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        editor.putString("updateTime", sdf.format(new Date()));
                        editor.apply();

                        return new Object[]{nowWeather, forecast, aqi, suggest, hourlyWeather};
                    } finally {
                        response0.close();
                        response1.close();
                        response2.close();
                        response3.close();
                        response4.close();
                    }
                }
        ).observeOn(AndroidSchedulers.mainThread())
        .subscribe(
                results -> {
                    showNowWeatherInfo((NowWeather)results[0]);
                    showForecastInfo((Forecast)results[1]);
                    showAQIInfo((AQI)results[2]);
                    showSuggestInfo((Suggest)results[3]);
                    showHourlyWeatherInfo((HourlyWeather)results[4]);

                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String currentTime = sdf.format(new Date());
                    binding.includeTitle.titleUpdateTime.setText(currentTime);

                    binding.swipeRefresh.setRefreshing(false);
                },
                throwable -> {
                    throwable.printStackTrace();
                    runOnUiThread(() -> {
                        Toast.makeText(WeatherActivity.this, "获取天气信息失败", Toast.LENGTH_SHORT).show();
                        binding.swipeRefresh.setRefreshing(false);
                    });
                }
        );
    }

    private void showNowWeatherInfo(NowWeather nowWeather) {
        if (nowWeather != null && nowWeather.getCode().equals("200")) {
            String temp = nowWeather.getNow().getTemp();
            binding.includeNow.weatherInfoText.setText(nowWeather.getNow().getText());
            binding.includeNow.degreeText.setText(String.format("%s °C", temp));
        } else {
            Toast.makeText(this, "获取实时天气信息出错！", Toast.LENGTH_SHORT).show();
        }
    }

    private void showSuggestInfo(Suggest suggest) {
        if (suggest != null && suggest.getCode().equals("200")) {
            binding.includeSuggestion.comfortText.setText(String.format("舒适度指数: \n %s \n %s",
                    suggest.getDaily().get(2).getCategory(),
                    suggest.getDaily().get(2).getText()));
            binding.includeSuggestion.sportText.setText(String.format("运动指数: \n %s \n %s",
                    suggest.getDaily().get(0).getCategory(),
                    suggest.getDaily().get(0).getText()));
            binding.includeSuggestion.wearText.setText(String.format("穿衣指数: \n %s \n %s",
                    suggest.getDaily().get(1).getCategory(),
                    suggest.getDaily().get(1).getText()));
        } else {
            Toast.makeText(this, "获取天气指数出错！", Toast.LENGTH_SHORT).show();
        }
    }

    private void showAQIInfo(AQI aqi) {
        if (aqi != null && aqi.getCode().equals("200")) {
            binding.includeAqi.aqiText.setText(aqi.getNow().getAqi());
            binding.includeAqi.pm25Text.setText(aqi.getNow().getPm2p5());
        } else {
            Toast.makeText(this, "获取实时空气质量出错！", Toast.LENGTH_SHORT).show();
        }
    }

    private void showForecastInfo(Forecast forecast) {
        if (forecast != null && forecast.getCode().equals("200")) {
            binding.includeForecast.forecastLayout.removeAllViews();
            for (Forecast.DailyDTO dailyDTO : forecast.getDaily()) {
                View view = LayoutInflater.from(this).inflate(R.layout.forecast_item, binding.includeForecast.forecastLayout, false);
                TextView dateText = (TextView) view.findViewById(R.id.date_text);
                TextView infoText = (TextView) view.findViewById(R.id.info_text);
                TextView maxText = (TextView) view.findViewById(R.id.max_text);
                TextView minText = (TextView) view.findViewById(R.id.min_text);
                ImageView weatherIcon = (ImageView) view.findViewById(R.id.weather_icon);

                dateText.setText(dailyDTO.getFxDate());
                String weatherText = dailyDTO.getTextDay();
                infoText.setText(weatherText);
                maxText.setText(dailyDTO.getTempMax());
                minText.setText(dailyDTO.getTempMin());

                // 根据天气文本设置对应的图标
                setWeatherIcon(weatherIcon, weatherText);

                binding.includeForecast.forecastLayout.addView(view);
            }
        } else {
            Toast.makeText(this, "获取未来7天天气预报出错！", Toast.LENGTH_SHORT).show();
        }
    }

    private void showHourlyWeatherInfo(HourlyWeather hourlyWeather) {
        if (hourlyWeather != null && hourlyWeather.getCode().equals("200")) {
            binding.includeHourly.hourlyForecastLayout.removeAllViews();
            
            for (HourlyWeather.HourlyDTO hourly : hourlyWeather.getHourly()) {
                View view = LayoutInflater.from(this).inflate(
                    R.layout.hourly_forecast_item, 
                    binding.includeHourly.hourlyForecastLayout, 
                    false);
                
                TextView timeText = view.findViewById(R.id.time_text);
                ImageView weatherIcon = view.findViewById(R.id.weather_icon);
                TextView tempText = view.findViewById(R.id.temp_text);

                // 格式化时间，只显示小时
                String time = hourly.getFxTime().substring(11, 16);
                timeText.setText(time);
                
                // 设置天气图标
                setWeatherIcon(weatherIcon, hourly.getText());
                
                // 设置温度
                tempText.setText(String.format("%s°", hourly.getTemp()));

                binding.includeHourly.hourlyForecastLayout.addView(view);
            }
        } else {
            Toast.makeText(this, "获取时段天气信息失败", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 根据天气文本设置对应的图标
     * @param imageView 要设置图标的ImageView
     * @param weatherText 天气文本描述
     */
    private void setWeatherIcon(ImageView imageView, String weatherText) {
        if (weatherText == null) {
            imageView.setImageResource(R.drawable.sunny); // 默认晴天图标
            return;
        }

        // 根据天气描述选择对应的图标
        if (weatherText.contains("晴")) {
            imageView.setImageResource(R.drawable.sunny);
        } else if (weatherText.contains("多云") || weatherText.contains("阴")) {
            imageView.setImageResource(R.drawable.cloudy);
        } else if (weatherText.contains("阴")) {
            imageView.setImageResource(R.drawable.overcast);
        } else if (weatherText.contains("雨")) {
            imageView.setImageResource(R.drawable.rain);
        } else {
            // 默认图标
            imageView.setImageResource(R.drawable.sunny);
        }
    }
    /**
     * 更新城市信息并请求新城市的天气
     * @param province 省份名称
     * @param city 城市名称
     * @param county 县/区名称
     * @param weatherId 天气ID
     */
    public void updateCityInfo(String province, String city, String county, String weatherId) {
        // 更新成员变量
        current_province = province;
        current_city = city;
        current_county = county;

        // 更新UI显示
        binding.includeTitle.titleCity.setText(String.format("%s %s %s",
            safeString(current_province),
            safeString(current_city),
            safeString(current_county)));

        // 更新右上角的时间显示
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentTime = sdf.format(new Date());
        binding.includeTitle.titleUpdateTime.setText(currentTime);

        // 处理天气ID并请求天气
        if (weatherId != null && weatherId.length() > 2) {
            String processedWeatherId = weatherId.substring(2);
            mWeatherId = processedWeatherId; // 保存处理后的天气ID
            requestWeather(processedWeatherId);
        } else {
            Toast.makeText(this, "天气ID格式错误", Toast.LENGTH_SHORT).show();
            binding.swipeRefresh.setRefreshing(false);
        }
    }
}